from django.shortcuts import get_object_or_404
from .models import QueueList, QueueMember
from django.http import JsonResponse, HttpResponse, Http404
import random


def ql_to_dict(ql):
    d = {
        'pk': ql.id,
        'name': ql.name,
        'code': ql.code,
        'uuid': ql.uuid,
        'current': ql.current,
        'create_time': ql.create_time,
        'last_call_time': ql.last_call_time,
        'avg_waiting_time': ql.avg_waiting_time,
        'bulletin': ql.bulletin,
    }
    return d


def qm_to_dict(qm):
    d = {
        'pk': qm.id,
        'name': qm.name,
        'uuid': qm.uuid,
        'queue_list': qm.queue_list,
        'create_time': qm.create_time,
        'comment': qm.comment,
    }
    return d


def qms_to_dict(qms):
    r = []
    for qm in qms:
        d = qm_to_dict(qm)
        r.append(d)
    return r


# GET for both caller and queuer - check whether in queue
# POST for caller - create a QueueList
# DELETE for caller - delete a QueueList
def queue(request, userid):
    if request.method == 'GET':
        qs = QueueList.objects.filter(uuid=userid)
        if qs.exists():
            return JsonResponse(ql_to_dict(qs.first()))
        elif qs.exists():
            qs = QueueMember.objects.filter(uuid=userid)
            return JsonResponse(qms_to_dict(qs))
        else:
            return Http404('User Not Found in Queue')
    elif request.method == 'POST':
        if QueueList.objects.filter(uuid=userid).exists():
            return HttpResponse(status=400, content='QueryList Already Exists')
        code = random.randint(0, 9999)
        while QueueList.objects.filter(code=code).exists():
            code = random.randint(0, 9999)
        ql = QueueList.objects.create(uuid=userid, name=request.POST['name'], code=code)
        return JsonResponse(ql_to_dict(ql))
    elif request.method == 'DELETE':
        ql = get_object_or_404(QueueList, uuid=userid)
        ql.delete()
        return HttpResponse(status=204, content='Deleted')


# GET for caller - next queuer
def next_queue(request, userid):
    if request.method == 'GET':
        qs = get_object_or_404(QueueList, uuid=userid)
        qs.current = qs.current + 1


# GET for both caller and queuer - check current queue
def check_queue(request, code):
    if request.method == 'GET':
        ql = get_object_or_404(QueueList, code=code)
        qms = QueueMember.objects.filter(query_list=ql).order_by('create_time')
        resp = {
            'query_list': ql_to_dict(ql),
            'query_members': qms_to_dict(qms),
        }
        return JsonResponse(resp)


# POST for queuer
def join_queue(request, code):
    if request.method == 'POST':
        ql = get_object_or_404(QueueList, code=code)
        if QueueMember.objects.filter(query_list=ql, uuid=request.POST.get('uuid')).exists():
            return HttpResponse(status=400, content='Already Joined')
        qm = QueueMember.objects.create(queue_list=ql, uuid=request.POST.get('uuid'), name=request.POST.get('name'))
        return JsonResponse(qm_to_dict(qm))


# POST for queuer
def leave_queue(request, code):
    if request.method == 'POST':
        ql = get_object_or_404(QueueList, code=code)
        qm = get_object_or_404(QueueList, queue_list=ql, uuid=request.POST.get('uuid'))
        qm.delete()
        return HttpResponse(status=204, content='Deleted')


# POST for caller
def update_caller(request, code):
    if request.method == 'POST':
        get_object_or_404(QueueList, code=code)
        ql = QueueList.objects.get(code=code)
        ql.update(name=request.POST.get('name'), bulletin=request.POST.get('bulletin'))
        return JsonResponse(ql_to_dict(ql))


# POST for queuer
def update_queuer(request, code):
    if request.method == 'POST':
        ql = get_object_or_404(QueueList, code=code)
        get_object_or_404(QueueMember, uuid=request.POST.get('uuid'), queue_list=ql)
        qm = QueueMember.objects.get(uuid=request.POST.get('uuid'), queue_list=ql)
        qm.update(name=request.POST.get('name'), comment=request.POST.get('comment'))
        return JsonResponse(qm_to_dict(qm))
